<template>
  <div ref="container"></div>
</template>

<script setup lang="ts">
import * as THREE from 'three'
// 补间动画库
import gsap from 'gsap'
// gui控制面板
import * as dat from 'dat-gui'
// 轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'

import {onMounted, ref} from "vue";
import useWindowResize from "@/hook/useWindowResize";

const container = ref<HTMLElement>()

const gui = new dat.GUI()
let cube: THREE.Mesh
let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let controls: OrbitControls
let renderer: THREE.WebGLRenderer

const {width, height} = useWindowResize(213, 53, () => {
  if (camera) {
    camera.aspect = width.value! / height.value! // 更新相机宽高比
    camera.updateProjectionMatrix(); // 更新投影矩阵
    renderer.setSize(width.value!, height.value!)
  }
})

onMounted(() => {
  initScene() // 场景初始化
  initCamera() // 初始化相机
  initRenderer() // 初始化渲染器
  initControls()// 初始化控制器
  animate()
})

let anim: gsap.core.Tween
const initScene = () => {
  scene = new THREE.Scene()
  // 1. 添加物体
  const geometry = new THREE.BoxGeometry(3, 3, 1);
  // MeshBasicMaterial
  const material = new THREE.MeshLambertMaterial({color: 0x53a753});
  material.transparent = true// 开启透明
  material.opacity = 0.5
  cube = new THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial>(geometry, material);
  cube.scale.y = 1 // 缩放
  cube.rotateX(10)
  cube.rotateZ(10)
  scene.add(cube);
  anim = gsap.to(cube.position, {y: 15, duration: 1, ease: "easeInOut", repeat: -1, yoyo: true})
  // 环境光
  const ambientLight = new THREE.AmbientLight(0xffcccc)
  scene.add(ambientLight)
  // 点光源
  const pointLight = new THREE.PointLight(0xffffff, 0.9)
  pointLight.position.set(15, 20, 5)
  scene.add(pointLight)
  // 光源帮助
  const pointLightHelper= new THREE.PointLightHelper(pointLight,2)
  scene.add(pointLightHelper)

  // 2.添加坐标轴辅助器
  const axesHelper = new THREE.AxesHelper(10)
  scene.add(axesHelper)

  // 3.gui添加
  gui.add(cube.position, "x").min(0).max(10).name("设置X轴值")
  const parames = {
    color: "#53a753",
    animate: true
  }
  gui.addColor(parames, "color").onChange((value: string) => {
    (cube.material as THREE.MeshBasicMaterial).color.set(value)
  })
  gui.add(parames, "animate").name("是否进行运动").onChange((flag: boolean) => {
    if (flag) {
      anim.resume()
    } else {
      anim.pause()
    }
  })
  // 添加文件夹
  const folder = gui.addFolder("立方体设置")
  folder.add(cube.material, "wireframe").name("是否显示纹理")

}

const initCamera = () => {
  camera = new THREE.PerspectiveCamera(75, width.value / height.value, 0.1, 1000)
  camera!.position!.z = 25
  camera!.position!.x = 5
  camera!.position!.y = 5
  camera.lookAt(0, 0, 0)
  scene!.add(camera);
}

const initRenderer = () => {
  renderer = new THREE.WebGLRenderer()
  renderer?.setPixelRatio(window.devicePixelRatio) // 屏幕像素比
  renderer?.setSize(width.value, height.value) // 渲染尺寸
  // renderer!.setClearColor(new THREE.Color(0xffccccc))
  container.value?.appendChild(renderer!.domElement)
}

const initControls = () => {
  controls = new OrbitControls(camera!, renderer!.domElement)
  controls.update()
}


const render = () => {
  /* if (cube.position.x > 10) {
    cube.position.x = 0
  } else {
    cube.position.x += 0.01
  } */

  renderer.render(scene!, camera!)
}

const animate = () => {
  renderer?.setAnimationLoop(render)
}


</script>

<style scoped>

</style>
